﻿using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using LiSAClient.Core;
using LiSAClient.Core.Interfaces;
using LiSAClient.Core.Messages;
using LiSAClient.Core.Models;
using LiSAClient.Core.Services;
using LiSAClient.Core.Services.Factories;
using LiSAClient.Core.Viewmodel;
using LiSAClient.LiSAService;

namespace LiSAClient.WpfClient.ViewModel.Projects
{
    public class NewProject_Step6ViewModel : ContentViewModel, ICommitable
    {
        #region Observable Objects
        public ICommand Commit { get; private set; }

        public ICommand PreviousStep { get; private set; }

        public ICommand NextStep { get; private set; }

        public ICommand AddDecisionPoint { get; private set; }

        public ICommand AddStage { get; private set; }

        private List<string> decisionPoints;
        public List<string> DecisionPoints
        {
            get
            {
                return this.decisionPoints;
            }

            set
            {
                this.Set(() => this.DecisionPoints, ref this.decisionPoints, value);
            }
        }

        private string newDecisionPoint;
        public string NewDecisionPoint
        {
            get
            {
                return this.newDecisionPoint;
            }

            set
            {
                this.Set(() => this.NewDecisionPoint, ref this.newDecisionPoint, value);
            }
        }

        private ProjectStage newProjectStage;
        public ProjectStage NewProjectStage
        {
            get
            {
                return this.newProjectStage;
            }

            set
            {
                this.Set(() => this.NewProjectStage, ref this.newProjectStage, value);
            }
        }

        private ProjectStage selectedProjectStage;
        public ProjectStage SelectedProjectStage
        {
            get
            {
                return this.selectedProjectStage;
            }

            set
            {
                this.Set(() => this.SelectedProjectStage, ref this.selectedProjectStage, value);
            }
        }

        private Project project;
        public Project Project
        {
            get
            {
                return this.project;
            }

            set
            {
                this.Set(() => this.Project, ref this.project, value);
            }
        }
        #endregion

        #region Initializers

        public NewProject_Step6ViewModel(Project proj)
        {
            this.Project = proj;
            this.Commit = new RelayCommand(SaveProject);
            this.PreviousStep = new RelayCommand(DoPreviousStep);
            this.NextStep = new RelayCommand(DoNextStep);
            this.AddDecisionPoint = new RelayCommand(DoAddDecisionPoint);
            this.AddStage = new RelayCommand(DoAddStage);
            this.NewProjectStage = new ProjectStage{DecisionPoints = new List<string>()};
        }

        public override void OnPresented()
        {
            if(Project.Stages == null) Project.Stages = new List<ProjectStage>();
            if (Project.Stages.Any(x => x.Description == "Inclusion Exclusion"))
            {
                return;
            }

            // Add default inclusion/exclusion Stage (BUSINESS RULE!)
            this.Project.Stages.Add(new ProjectStage
            {
                Stage = 0, 
                DecisionPoints = new List<string>{"In", "Out"},
                Description = "Inclusion Exclusion",
            });
        }

        #endregion

        #region methods
        /// <summary>
        /// Move to the previous step in the wizard
        /// </summary>
        public void DoPreviousStep()
        {
            this.Presenter.PresentContent(new NewProject_Step5ViewModel(this.Project));
        }

        /// <summary>
        /// Move to the next step in the wizard
        /// </summary>
        public void DoNextStep()
        {
            this.Presenter.PresentContent(new NewProject_Step7ViewModel(this.Project));
        }

        /// <summary>
        /// Add a decision point to the stage
        /// </summary>
        public void DoAddDecisionPoint()
        {
            if (string.IsNullOrWhiteSpace(this.NewDecisionPoint) || this.NewProjectStage.DecisionPoints.Any(x => x.ToLower().Trim() == this.NewDecisionPoint.Trim().ToLower()))
            {
                return;
            }
            var newPoints = new List<string>(this.NewProjectStage.DecisionPoints) {this.NewDecisionPoint};
            this.DecisionPoints = newPoints;
            this.NewProjectStage = new ProjectStage {DecisionPoints = newPoints};
            this.NewDecisionPoint = string.Empty;
        }

        /// <summary>
        /// Add the stage to the Project
        /// </summary>
        public void DoAddStage()
        {
            if (string.IsNullOrWhiteSpace(this.NewProjectStage.Description) ||
                this.NewProjectStage.DecisionPoints.Count < 1)
            {
                return;
            }
            this.NewProjectStage.Stage = this.Project.Stages.Count;
            var newStages = new List<ProjectStage>(this.Project.Stages) { this.NewProjectStage };
            this.Project.Stages = newStages;
            this.NewProjectStage = new ProjectStage{DecisionPoints = new List<string>()};
            this.DecisionPoints = new List<string>();
        }

        /// <summary>
        /// Save the project and close the window
        /// </summary>
        public void SaveProject()
        {
            // Ensure legality
            if (string.IsNullOrWhiteSpace(this.Project.Title))
            {
                Messenger.Default.Send(new ShowNotificationMessage
                {
                    NotificationType = NotificationType.Warning,
                    Header = "Warning!",
                    Body = "The project must have a title."
                });
                return;
            }
            if (string.IsNullOrWhiteSpace(this.Project.Description))
            {
                Messenger.Default.Send(new ShowNotificationMessage
                {
                    NotificationType = NotificationType.Warning,
                    Header = "Warning!",
                    Body = "The project must have a description."
                });
                return;
            }

            this.Project.ProjectLead = AppContext.CurrentContext.User.ID;
            this.Project.CurrentPhase = 0;

            ServiceFactory.Instance.Get<ProjectService>().CreateNewProject(this.Project);

            // Close the window
            if (this.Presenter != null)
            {
                this.Presenter.SendClosingRequest();
            }
        }
        #endregion
    }
}
